import StaticLoadTraits from './traits'
import DynamicLoadParams from './params'
import DynamicLoadDatas from './datas'
import { IS_EQUAL, BUILD_PROPERTIES } from '../internal'

function BuildTraitsProperty(datas, core, skipNonExistent = true) {
  const { props, factory } = StaticLoadTraits()
  return BUILD_PROPERTIES(props, factory, datas, core, skipNonExistent)
}

function BuildParamsProperty(sType, datas, core, skipNonExistent = true) {
  const { props, factory } = DynamicLoadParams(sType)
  console.log('BuildParamsProperty:', sType, props, factory)
  return BUILD_PROPERTIES(props, factory, datas, core, skipNonExistent)
}

function BuildDatasProperty(sType, datas, core, skipNonExistent = true) {
  const { props, factory } = DynamicLoadDatas(sType)
  return BUILD_PROPERTIES(props, factory, datas, core, skipNonExistent)
}

function GetProperties(part, core) {
  // in -- 内部数据(图元基本特性和几何参数)
  // out -- 外部数据(图元扩展属性数据)
  return { in: core.getParam3(part), out: core.getData3(part) }
}

function BuildProperty(sType, data, core, skipNonExistent = true) {
  // 构造用于属性面板交互的属性几何
  const props = {
    traits: null,
    params: null,
    datas: null
  }
  if (data.in !== null) {
    // 1、从内部数据中提取CAD图元基本特性
    props['traits'] = BuildTraitsProperty(data.in, core, skipNonExistent)
    // 2、从内部数据中提取图元的几何参数(动态加载@/vng/Property/params/entity下的子模块)
    props['params'] = BuildParamsProperty(sType, data.in, core, skipNonExistent)
  }
  if (data.out !== null) {
    // 3、从外部数据中提取图元的属性数据(动态加载@/vng/Property/datas/entity下的子模块)
    props['datas'] = BuildDatasProperty(sType, data.out, core, skipNonExistent)
  }
  return props
}

const Property = {}

// 读取图元所有数据
Property.Get = function(part, core) {
  const sType = core.getType(part)
  if (!sType) return null

  // 获取图元的内部和外部数据
  const data = GetProperties(part, core)
  if (!data) return null

  // 构造用于属性面板交互的属性集合
  return BuildProperty(sType, data, core)
}

Property.Set = function(part, args, core) {
  const s = core.getParamSet(part, args)
  console.log(s)
  if (!s) return
  const params = {}
  const datas = {}
  for (const field in args) {
    if (s.has(field)) {
      params[field] = args[field]
    } else {
      datas[field] = args[field]
    }
  }
  core.fastSetParam([part], params)
  core.fastSetData([part], datas)
}

Property.Get2 = function(parts, core) {
  if (!parts || parts.length === 0) return null
  if (parts.length === 1) {
    return Property.Get(parts[0], core)
  }

  // 取第一个图元, 得到图元类型
  const part = parts[0]
  if (!part) return null
  const sType = core.getType(part)

  // 统计字段出现的次数
  // { count: 0, same: true, last: null }
  const IN = {}
  const OUT = {}
  parts.forEach(part => {
    const data = GetProperties(part, core)
    // console.log(data)
    if (data) {
      for (const key in data.in) {
        if (!IN.hasOwnProperty(key)) {
          IN[key] = {
            count: 0,
            same: true,
            first: data.in[key]
          }
        }
        IN[key].count += 1
        IN[key].same = IN[key].same
          ? IS_EQUAL(IN[key].first, data.in[key])
          : false
      }
      for (const key in data.out) {
        if (!OUT.hasOwnProperty(key)) {
          OUT[key] = {
            count: 0,
            same: true,
            first: data.out[key]
          }
        }
        OUT[key].count += 1
        OUT[key].same = OUT[key].same
          ? IS_EQUAL(OUT[key].first, data.out[key])
          : false
      }
    }
  })
  // 合并后的数据
  const mergedData = {
    in: null,
    out: null
  }
  // console.log('IN:', IN)
  for (const key in IN) {
    if (IN[key].count !== parts.length) continue
    if (!mergedData.in) mergedData.in = {}
    mergedData.in[key] = IN[key].same ? IN[key].first : ''
  }
  for (const key in OUT) {
    if (OUT[key].count !== parts.length) continue
    if (!mergedData.out) mergedData.out = {}
    mergedData.out[key] = OUT[key].same ? OUT[key].first : ''
  }
  console.log('合并后的数据:', mergedData)
  // 使用合并后的数据, 构造用于属性面板交互的属性集合
  return BuildProperty(sType, mergedData, core)
}

Property.ArrangeArgs = function(args) {
  const newArgs = { ...args }
  for (const key in args) {
    if (key === 'loc') {
      const pt = args[key]
      if (pt) {
        newArgs[key] = `${pt.x} ${-1 * pt.y}`
      }
    }
  }
  return newArgs
  // return args
}

export default Property
